package com.zjcode.cdcer.service.impl;

import com.chinatechstar.component.commons.entity.MPage;
import com.chinatechstar.component.commons.result.PaginationBuilder;
import com.chinatechstar.component.commons.service.BaseService;
import com.chinatechstar.component.commons.supports.PageData;
import com.chinatechstar.component.commons.utils.RecursiveListUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zjcode.cdcer.mapper.TkmSysOrgMapper;
import com.zjcode.cdcer.mapper.TkmSysUserMapper;
import com.zjcode.cdcer.mapper.ZjcodeSysRegionMapper;
import com.zjcode.cdcer.model.TkmSysOrg;
import com.zjcode.cdcer.model.TkmSysUser;
import com.zjcode.cdcer.model.ZjcodeSysRegion;
import com.zjcode.cdcer.service.TkmSysOrgService;

import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * @ClassName:TkmSysOrgServiceImpl
 * @功能：
 * @author：wlei
 * @日期：2022/8/5-04:02
 **/
@Service
public class TkmSysOrgServiceImpl implements TkmSysOrgService, BaseService {

    @Autowired
    private TkmSysOrgMapper sysOrgMapper;

    @Autowired
    private ZjcodeSysRegionMapper zjcodeSysRegionMapper;

    @Autowired
    private TkmSysUserMapper sysUserMapper;

    @Override
    public Map<String, Object> listAllData(PageData pageData) {
        MPage mPage = getPageInfo(pageData);
        Page<Object> page = PageHelper.startPage(mPage.getCurrentPage(), mPage.getPageSize());
        List<LinkedHashMap<String, Object>> list = sysOrgMapper.listAllData(pageData);

        return PaginationBuilder.buildResult(list,
                                             page.getTotal(),
                                             mPage.getCurrentPage(),
                                             mPage.getPageSize());
    }

    @Override
    public LinkedHashMap<String, Object> getAllProvince() {
        LinkedHashMap<String, Object> resultMap = new LinkedHashMap<>();
        List<LinkedHashMap<String, Object>> resultList = zjcodeSysRegionMapper.selectAllProvince();
        resultMap.put("list", resultList);
        return resultMap;
    }

    @Override
    public Map<String, Object> getAllProvinceCity(PageData pageData) {
        LinkedHashMap<String, Object> resultMap = new LinkedHashMap<>();
        String user = (String) pageData.get("user");

        // 父级机构的区域编码
        String parentReginCode = "";
        if (user != null) {
            TkmSysUser sysUser = sysUserMapper.selectByPrimaryKey(Long.parseLong(user));
            Long orgId = sysUser.getOrgId();
            TkmSysOrg org = sysOrgMapper.selectByPrimaryKey(orgId);
            String ancestors = org.getAncestors();
            String regionAncestors = org.getRegionAncestors();
            // 如果是县级疾控中心,则需要取出区域编码组中的第二位
            if (org
                .getOrgType()
                .equals("district")) {
                if (regionAncestors != null && regionAncestors.contains(",")) {
                    String[] split = regionAncestors.split(",");
                    parentReginCode = split[split.length - 2 > 0 ? split.length - 2 : 0];
                }
            } else {
                if (regionAncestors != null && regionAncestors.contains(",")) {
                    String[] split = regionAncestors.split(",");
                    parentReginCode = split[split.length - 1];
                }
            }


        }

        List<LinkedHashMap<String, Object>> allCities = zjcodeSysRegionMapper.getAllCities(pageData);
        if (!StringUtils.isEmpty(parentReginCode)) {
            // 执行数据过滤,如果是地市级别的机构，则只显示该机构下的数据,默认指挥有一条数据
            String finalParentReginCode = parentReginCode;
            allCities.removeIf(each -> {
                String regionCode = (String) each.get("id");
                return !regionCode.equals(finalParentReginCode);
            });
        }
        if (!CollectionUtils.isEmpty(allCities)) {
            resultMap.put("list", allCities);
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> getDistrictAndStreet(PageData pageData) {
        //所有数据集合
        List<LinkedHashMap<String, Object>> zjcodeSysRegions = new ArrayList<>();
        //得到区数据
        List<LinkedHashMap<String, Object>> districts = zjcodeSysRegionMapper.getAllDistricts(
            pageData);
        List<String> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(districts)) {
            districts
                .parallelStream()
                .parallel()
                .forEach(region -> {
                    list.add(region
                                 .get("key")
                                 .toString());
                });
            zjcodeSysRegions.addAll(districts);
        }
        //拿街道等数据
        if (!CollectionUtils.isEmpty(list)) {
            List<LinkedHashMap<String, Object>> streets = zjcodeSysRegionMapper.getAllStreets(list);
            zjcodeSysRegions.addAll(streets);
        }
        LinkedHashMap<String, Object> resultMap = new LinkedHashMap<>();
        List<LinkedHashMap<String, Object>> sysRegions = buildTree(zjcodeSysRegions,
                                                                   (pageData.get("parentRegionCode")).toString());
        if (!CollectionUtils.isEmpty(sysRegions)) {
            resultMap.put("list", sysRegions);
        }
        return resultMap;
    }

    @Override
    public List<LinkedHashMap<String, Object>> exportOrgData(PageData pageData) {
        //返回数据集合
        List<LinkedHashMap<String, Object>> objects = new ArrayList<>();
        //查询导出的机构数据
        List<LinkedHashMap<String, Object>> maps = sysOrgMapper.exportOrgData(pageData);
        //适配导出代码
        maps
            .stream()
            .forEach(map -> {
                LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
                Object orgName = map.get("org_name");
                Object provinceName = map.get("province_name");
                Object cityName = map.get("city_name");
                Object regionName = map.get("region_name");
                Object regionCode = map.get("region_code");
                Object address = map.get("address");
                Object createTime = map.get("create_time");

                linkedHashMap.put("org_name", Objects.nonNull(orgName) ? orgName : "");
                linkedHashMap.put("province_name",
                                  Objects.nonNull(provinceName) ? provinceName : "");
                linkedHashMap.put("city_name", Objects.nonNull(cityName) ? cityName : "");
                linkedHashMap.put("region_name", Objects.nonNull(regionName) ? regionName : "");
                linkedHashMap.put("region_code", Objects.nonNull(regionCode) ? regionCode : "");
                linkedHashMap.put("address", Objects.nonNull(address) ? address : "");
                linkedHashMap.put("create_time",
                                  Objects.nonNull(createTime) ? new SimpleDateFormat(
                                      "yyyy-MM-dd HH:mm:ss").format(createTime) : "");
                objects.add(linkedHashMap);
            });
        return objects;
    }

    @Override
    public String getRegionCode(String orgId) {
        return sysOrgMapper.getRegionCode(orgId);
    }

    @Override
    public String getExFlag2(String orgId) {
        return sysOrgMapper.getExFlag2(orgId);
    }

    private List<LinkedHashMap<String, Object>> buildTree(List<LinkedHashMap<String, Object>> regionList,
                                                          String parentRegionCode) {
        List<LinkedHashMap<String, Object>> rootList = new ArrayList<>();
        regionList
            .stream()
            .forEach(region -> {
                if (region
                    .get("parentId")
                    .equals(parentRegionCode)) {
                    rootList.add(region);
                }
            });
        regionList
            .stream()
            .forEach(region -> {
                childrenMenu(regionList, region, parentRegionCode);
            });
        return rootList;
    }

    private LinkedHashMap<String, Object> childrenMenu(List<LinkedHashMap<String, Object>> regionList,
                                                       LinkedHashMap<String, Object> region,
                                                       String parentRegionCode) {
        List<LinkedHashMap<String, Object>> children = new ArrayList<>();
        regionList
            .stream()
            .forEach(zjcodeSysRegion -> {
                if (zjcodeSysRegion
                    .get("parentId")
                    .equals(region.get("key"))) {
                    children.add(childrenMenu(regionList, zjcodeSysRegion, parentRegionCode));
                }
            });
        region.put("children", children);
        return region;
    }
}
